package com.yeyupiaoling.testaiui;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.iflytek.aiui.AIUIAgent;
import com.iflytek.aiui.AIUIConstant;
import com.iflytek.aiui.AIUIEvent;
import com.iflytek.aiui.AIUIListener;
import com.iflytek.aiui.AIUIMessage;
import com.yeyupiaoling.testaiui.adapter.MyAdapter;
import com.yeyupiaoling.testaiui.bean.MsgContent;
import com.yeyupiaoling.testaiui.utils.Utils;

import org.json.JSONObject;

import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;

import okhttp3.OkHttpClient;
//main中assets/cfg/aiui_phone.json设置APPid
public class MainActivity extends AppCompatActivity {
    private static final String TAG = MainActivity.class.getName();
    private static final int REQUEST_CODE_WRITE_SETTINGS = 2;
    private static final int REQUEST_CODE_PERMISSION = 1;
    // 对话界面
    private MyAdapter mAdapter;
    private ArrayList<MsgContent> mList = new ArrayList<>();//信息列表
    private MsgContent msgContent;
    private RecyclerView messageList;

    // 意图
    private static final String WEATHER = "IFLYTEK.weather";
    private static final String MUSIC = "IFLYTEK.musicX";

    private static final OkHttpClient client = new OkHttpClient();

    // AIUI
    private int mAIUIState;//标识状态
    private AIUIAgent mAIUIAgent;//定义AIUIagent
    private int wakeUpNumber = 0;
    private byte[] writeData;
    private AIUIListener mAIUIListener = new AIUIListener() {
        @Override //用于接受AIUI SDK抛出事件的监听器
        public void onEvent(AIUIEvent event) {
            switch (event.eventType) {
                //事件触发的情况
                case AIUIConstant.EVENT_WAKEUP:
                    // 唤醒事件
                    Log.i(TAG, "唤醒事件");
                    wakeUpEvent(event);
                    break;
                case AIUIConstant.EVENT_RESULT:
                    // 结果解析事件
                    Log.i(TAG, "结果解析事件");
                    aiuiResultAnalysisEvent(event);
                    break;
                case AIUIConstant.EVENT_VAD:
                    vadEvent(event);
                    break;
                case AIUIConstant.EVENT_START_RECORD:
                    // 开始录音
                    Log.i(TAG, "开始录音");
                    startRecordEvent(event);
                    break;
                case AIUIConstant.EVENT_STOP_RECORD:
                    // 停止录音
                    Log.i(TAG, "停止录音");
                    stopRecordEvent(event);
                    break;
                case AIUIConstant.EVENT_STATE:
                    // 状态事件
                    aiuiStateEvent(event);
                    break;
                case AIUIConstant.EVENT_ERROR:
                    //错误事件
                    Log.e(TAG, "错误: " + event.arg1 + "\n" + event.info);
                    break;
                default:
                    break;
            }
        }
    };
    private EditText editText;//输入框
    private Button changeTextAudioBtn;//切换按钮
    private Button sendAudioBtn;//发送语音按钮


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        // 申请权限
        if (!hasPermission()) {
            requestPermission();
        }
        //requestWriteSettings();

        //调用初始化界面
        initView();
        //调用初始化
        initData();
    }
    @SuppressLint("ClickableViewAccessibility")
    private void initView() {
        //绑定控件
        messageList = findViewById(R.id.rv_list);
        editText = findViewById(R.id.send_content_et);
        changeTextAudioBtn = findViewById(R.id.text_audio_btn);
        Button sendTextBtn = findViewById(R.id.send_text_btn);
        sendAudioBtn = findViewById(R.id.send_audio_btn);
        //点击后按钮修改样式
        changeTextAudioBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (changeTextAudioBtn.getText().equals("切换语音输入")) {
                    sendAudioBtn.setVisibility(View.VISIBLE);
                    changeTextAudioBtn.setText("切换文字输入");
                } else {
                    sendAudioBtn.setVisibility(View.GONE);
                    changeTextAudioBtn.setText("切换语音输入");
                }
            }
        });
        //监听发送信息按钮的点击
        sendTextBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String content = editText.getText().toString();//获取文本
                if (!content.equals("")){//如果不为空
                    editText.setText("");//输入框置空
                    sendText(content);//发送文本
                }else {
                    Toast.makeText(MainActivity.this, "消息不能为空！", Toast.LENGTH_SHORT).show();
                }
            }
        });
        //监听语音发送
        sendAudioBtn.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                if (event.getAction() == MotionEvent.ACTION_DOWN) {
                    wakeUpNumber = 1;
                    if (AIUIConstant.STATE_WORKING != mAIUIState) {
                        AIUIMessage wakeupMsg = new AIUIMessage(AIUIConstant.CMD_WAKEUP, 0, 0, "", null);
                        mAIUIAgent.sendMessage(wakeupMsg);
                    } else {
                        // 打开AIUI内部录音机，开始录音
                        String params1 = "sample_rate=16000,data_type=audio";
                        AIUIMessage writeMsg = new AIUIMessage(AIUIConstant.CMD_START_RECORD, 0, 0, params1, null);
                        mAIUIAgent.sendMessage(writeMsg);
                    }
                }
                if (event.getAction() == MotionEvent.ACTION_UP) {
                    AIUIMessage wakeupMsg = new AIUIMessage(AIUIConstant.CMD_STOP_RECORD, 0, 0, "", null);
                    mAIUIAgent.sendMessage(wakeupMsg);
                }
                return false;
            }
        });

        // 配置信息列表
        messageList.setLayoutManager(new LinearLayoutManager(this));
        mAdapter = new MyAdapter(this);
        messageList.setAdapter(mAdapter);
        messageList.scrollToPosition(mAdapter.getItemCount() - 1);

        // 显示对话时间
        SimpleDateFormat df = new SimpleDateFormat("HH:mm");
        msgContent = new MsgContent();
        msgContent.setType("time");//设置为时间类型
        msgContent.setMsg(df.format(new Date()));
        mList.add(msgContent);
        mAdapter.setData(mList);
    }

    // 初始化数据
    private void initData() {
        //创建AIUI实例
        mAIUIAgent = AIUIAgent.createAgent(getApplicationContext(), Utils.getAIUIParams(MainActivity.this), mAIUIListener);
    }
    //测试唤醒
    private void testWakeUp() {
        wakeUpNumber = 0;
        // 先发送唤醒消息，改变AIUI内部状态，只有唤醒状态才能接收语音输入
        if (AIUIConstant.STATE_WORKING != mAIUIState) {
            AIUIMessage wakeupMsg = new AIUIMessage(AIUIConstant.CMD_WAKEUP, 0, 0, "", null);
            mAIUIAgent.sendMessage(wakeupMsg);
        }
    }

    // 发送音频信息
    private void sendAudio(byte[] audio) {
        wakeUpNumber = 2;
        writeData = audio;
        if (AIUIConstant.STATE_WORKING != mAIUIState) {
            String params = "data_type=audio,sample_rate=16000";
            AIUIMessage msg = new AIUIMessage(AIUIConstant.CMD_WRITE, 0, 0, params, writeData);
            mAIUIAgent.sendMessage(msg);
        } else {
            AIUIMessage wakeupMsg = new AIUIMessage(AIUIConstant.CMD_WAKEUP, 1, 0, "", null);
            mAIUIAgent.sendMessage(wakeupMsg);
        }
    }

    // 显示发送消息
    private void showSend(String text){
        msgContent = new MsgContent();
        msgContent.setType("send");
        msgContent.setMsg(text);
        mList.add(msgContent);
        mAdapter.setData(mList);
        messageList.scrollToPosition(mAdapter.getItemCount()-1);
    }

    // 显示接收消息
    private void showReceive(String text){
        msgContent = new MsgContent();
        msgContent.setType("receive");
        msgContent.setMsg(text);
        mList.add(msgContent);
        mAdapter.setData(mList);
        messageList.scrollToPosition(mAdapter.getItemCount()-1);
    }

    // 发送文本信息
    private void sendText(String text) {
        wakeUpNumber = 3;
        writeData = text.getBytes();
        if (AIUIConstant.STATE_WORKING == mAIUIState) {
            String params = "data_type=text";
            AIUIMessage msg = new AIUIMessage(AIUIConstant.CMD_WRITE, 0, 0, params, writeData);
            mAIUIAgent.sendMessage(msg);
        } else {
            AIUIMessage wakeupMsg = new AIUIMessage(AIUIConstant.CMD_WAKEUP, 2, 0, "", null);
            mAIUIAgent.sendMessage(wakeupMsg);
        }
    }
//事件部分
    // 唤醒事件
    private void wakeUpEvent(AIUIEvent event) {
        if (wakeUpNumber == 0 || wakeUpNumber == 1) {
            // 打开AIUI内部录音机，开始录音
            String params1 = "sample_rate=16000,data_type=audio";
            AIUIMessage writeMsg = new AIUIMessage(AIUIConstant.CMD_START_RECORD, 0, 0, params1, null);
            mAIUIAgent.sendMessage(writeMsg);
        } else if (wakeUpNumber == 2) {
            // 发送音频数据
            String params = "data_type=audio,sample_rate=16000";
            AIUIMessage msg = new AIUIMessage(AIUIConstant.CMD_WRITE, 0, 0, params, writeData);
            mAIUIAgent.sendMessage(msg);
        } else if (wakeUpNumber == 3) {
            // 发送文本数据
            String params = "data_type=text";
            AIUIMessage msg = new AIUIMessage(AIUIConstant.CMD_WRITE, 0, 0, params, writeData);
            mAIUIAgent.sendMessage(msg);
        }
    }

    // 结果解析事件
    private void aiuiResultAnalysisEvent(AIUIEvent event) {
        try {
            JSONObject data = new JSONObject(event.info).getJSONArray("data").getJSONObject(0);
            String sub = data.getJSONObject("params").optString("sub");
            Log.d("结果", sub);
            JSONObject content = data.getJSONArray("content").getJSONObject(0);

            if (content.has("cnt_id")) {
                String cnt_id = content.getString("cnt_id");
                String resultStr = new String(event.data.getByteArray(cnt_id), StandardCharsets.UTF_8);
                JSONObject result = new JSONObject(resultStr);
                JSONObject intent = result.getJSONObject("intent");
                JSONObject answer = intent.getJSONObject("answer");
                String text = intent.getString("text");
                String answerText = answer.getString("text");
                if (sub.equals("nlp")){
                    showSend(text);
                }
                showReceive(answerText);
            }
        } catch (Throwable ignored) {
        }
    }


    // 语音前后端点事件
    private void vadEvent(AIUIEvent event) {
        if (AIUIConstant.VAD_BOS == event.arg1) {
            //语音前端点
        } else if (AIUIConstant.VAD_EOS == event.arg1) {
            //语音后端点
        }
    }


    // 开始录音事件
    private void startRecordEvent(AIUIEvent event) {
        if (wakeUpNumber == 0 || wakeUpNumber == 1) {
            Log.d(TAG, "请说话...");
        }
    }

    // 停止录音事件
    private void stopRecordEvent(AIUIEvent event) {
        Log.d(TAG, "请停止说话");
    }

    // AIUI状态事件
    private void aiuiStateEvent(AIUIEvent event) {
        mAIUIState = event.arg1;
        if (AIUIConstant.STATE_IDLE == mAIUIState) {
            // 闲置状态，AIUI未开启
        } else if (AIUIConstant.STATE_READY == mAIUIState) {
            // AIUI已就绪，等待唤醒
        } else if (AIUIConstant.STATE_WORKING == mAIUIState) {
            // AIUI工作中，可进行交互
        }
    }


    // 特殊权限申请
    private void requestWriteSettings() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (!Settings.System.canWrite(getApplicationContext())) {
                Intent intent = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);
                intent.setData(Uri.parse("package:" + getPackageName()));
                startActivityForResult(intent, REQUEST_CODE_WRITE_SETTINGS);
            }
        }
    }
    // 危险权限
    private boolean hasPermission() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            return checkSelfPermission(Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED &&
                    checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED &&
                    checkSelfPermission(Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED &&
                    checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED &&
                    checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
        } else {
            return true;
        }
    }
    // request permission
    private void requestPermission() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            requestPermissions(new String[]{Manifest.permission.RECORD_AUDIO,
                    Manifest.permission.ACCESS_FINE_LOCATION,
                   // Manifest.permission.READ_PHONE_STATE,
                    Manifest.permission.READ_EXTERNAL_STORAGE,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_CODE_PERMISSION);
        }
    }
}
